package com.kexio.test;

import com.kexio.auth.annotation.RequiresPermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.kexio.common.cache.RedisUtil;
import com.kexio.common.dto.Result;

import cn.dev33.satoken.stp.StpUtil;

/**
 * 缓存监控测试控制器
 * 
 * 用于测试和验证缓存监控功能是否正常工作
 * 
 * @author Kexio Team
 */
@RestController
@RequestMapping("/test/cache")
public class CacheMonitorTestController {
    
    @Autowired
    private RedisUtil redisUtil;
    
    /**
     * 测试缓存设置操作
     */
    @GetMapping("/set")
    public Result testCacheSet(@RequestParam(defaultValue = "test_key") String key,
                                  @RequestParam(defaultValue = "test_value") String value) {
        try {
            boolean success = redisUtil.set("kexio:test:" + key, value);
            return Result.success("缓存设置" + (success ? "成功" : "失败"));
        } catch (Exception e) {
            return Result.error("缓存设置异常: " + e.getMessage());
        }
    }
    
    /**
     * 测试缓存获取操作（命中）
     */
    @GetMapping("/get")
    public Result testCacheGet(@RequestParam(defaultValue = "test_key") String key) {
        try {
            Object value = redisUtil.get("kexio:test:" + key);
            boolean hit = (value != null);
            return Result.success("缓存获取" + (hit ? "命中" : "未命中"), value);
        } catch (Exception e) {
            return Result.error("缓存获取异常: " + e.getMessage());
        }
    }
    
    /**
     * 测试缓存获取操作（未命中）
     */
    @GetMapping("/miss")
    public Result testCacheMiss() {
        try {
            // 故意访问不存在的键来产生 miss
            String randomKey = "kexio:test:nonexistent_" + System.currentTimeMillis();
            Object value = redisUtil.get(randomKey);
            return Result.success("缓存未命中测试完成", value);
        } catch (Exception e) {
            return Result.error("缓存未命中测试异常: " + e.getMessage());
        }
    }
    
    /**
     * 测试缓存删除操作
     */
    @GetMapping("/delete")
    public Result testCacheDelete(@RequestParam(defaultValue = "test_key") String key) {
        try {
            long deleted = redisUtil.delete("kexio:test:" + key);
            return Result.success("缓存删除完成，删除了 " + deleted + " 个键");
        } catch (Exception e) {
            return Result.error("缓存删除异常: " + e.getMessage());
        }
    }
    
    /**
     * 批量操作测试
     */
    @GetMapping("/batch")
    public Result testBatchOperations() {
        try {
            // 批量设置
            for (int i = 0; i < 10; i++) {
                redisUtil.set("kexio:test:batch_" + i, "value_" + i);
            }
            
            // 批量获取（命中）
            for (int i = 0; i < 10; i++) {
                redisUtil.get("kexio:test:batch_" + i);
            }
            
            // 一些未命中操作
            for (int i = 0; i < 5; i++) {
                redisUtil.get("kexio:test:missing_" + i);
            }
            
            // 批量删除
            String[] keysToDelete = new String[10];
            for (int i = 0; i < 10; i++) {
                keysToDelete[i] = "kexio:test:batch_" + i;
            }
            redisUtil.delete(keysToDelete);
            
            return Result.success("批量操作测试完成：10次SET + 10次GET(命中) + 5次GET(未命中) + 10次DELETE");
            
        } catch (Exception e) {
            return Result.error("批量操作测试异常: " + e.getMessage());
        }
    }
    
    /**
     * 测试 Spring Cache 缓存操作（@Cacheable）
     */
    @GetMapping("/spring-cache/get")
    // ⚠️ 生产环境安全：移除@SaIgnore，增加权限控制
    @RequiresPermission("cache:test:view")
    @Cacheable(value = "test-cache", key = "#key")
    public Result testSpringCacheGet(@RequestParam(defaultValue = "spring_test") String key) {
        // 模拟数据库查询或复杂计算
        String value = "computed_value_" + System.currentTimeMillis();
        return Result.success("Spring Cache 获取完成", value);
    }
    
    /**
     * 测试 Spring Cache 缓存清除（@CacheEvict）
     */
    @GetMapping("/spring-cache/evict")
    @CacheEvict(value = "test-cache", key = "#key")
    public Result testSpringCacheEvict(@RequestParam(defaultValue = "spring_test") String key) {
        return Result.success("Spring Cache 清除完成: " + key);
    }
    
    /**
     * 测试 Spring Cache 批量操作
     */
    @GetMapping("/spring-cache/batch")
    public Result testSpringCacheBatch() {
        try {
            // 批量缓存操作
            for (int i = 0; i < 5; i++) {
                testSpringCacheGet("batch_key_" + i);  // 第一次会缓存
                testSpringCacheGet("batch_key_" + i);  // 第二次会命中
            }
            
            // 清除部分缓存
            for (int i = 0; i < 3; i++) {
                testSpringCacheEvict("batch_key_" + i);
            }
            
            return Result.success("Spring Cache 批量操作完成：5次缓存 + 5次命中 + 3次清除");
        } catch (Exception e) {
            return Result.error("Spring Cache 批量操作异常: " + e.getMessage());
        }
    }
    
    /**
     * 测试 SaToken 缓存操作
     */
    @GetMapping("/satoken/set")
    public Result testSaTokenSet(@RequestParam(defaultValue = "test_user") String userId) {
        try {
            // 模拟用户登录，SaToken 会缓存 Token
            StpUtil.login(userId);
            String token = StpUtil.getTokenValue();
            
            return Result.success("SaToken 缓存设置完成", token);
        } catch (Exception e) {
            return Result.error("SaToken 缓存设置异常: " + e.getMessage());
        }
    }
    
    /**
     * 测试 SaToken 缓存获取
     */
    @GetMapping("/satoken/get")
    public Result testSaTokenGet() {
        try {
            // 获取当前登录状态，会访问 SaToken 缓存
            boolean isLogin = StpUtil.isLogin();
            Object loginId = isLogin ? StpUtil.getLoginId() : null;
            
            return Result.success("SaToken 缓存获取完成", 
                "isLogin: " + isLogin + ", loginId: " + loginId);
        } catch (Exception e) {
            return Result.error("SaToken 缓存获取异常: " + e.getMessage());
        }
    }
    
    /**
     * 测试 SaToken 缓存删除
     */
    @GetMapping("/satoken/logout")
    public Result testSaTokenLogout() {
        try {
            // 退出登录，SaToken 会删除相关缓存
            StpUtil.logout();
            
            return Result.success("SaToken 缓存删除完成");
        } catch (Exception e) {
            return Result.error("SaToken 缓存删除异常: " + e.getMessage());
        }
    }
    
    /**
     * 验证监控数据的快速入口（增强版）
     */
    @GetMapping("/verify")
    public Result verifyMonitoring() {
        try {
            // 1. RedisUtil 操作
            redisUtil.set("kexio:test:verify", "monitoring_test");
            redisUtil.get("kexio:test:verify");    // 命中
            redisUtil.get("kexio:test:nonexistent"); // 未命中
            redisUtil.delete("kexio:test:verify");
            
            // 2. Spring Cache 操作
            testSpringCacheGet("verify_key");       // 缓存
            testSpringCacheGet("verify_key");       // 命中
            testSpringCacheEvict("verify_key");     // 清除
            
            // 3. SaToken 操作（如果可用）
            try {
                testSaTokenSet("verify_user");      // 登录缓存
                testSaTokenGet();                   // 状态检查
                testSaTokenLogout();                // 登出清除
            } catch (Exception e) {
                // SaToken 操作失败不影响整体验证
            }
            
            return Result.success("全面监控验证操作完成！包括 RedisUtil + Spring Cache + SaToken");
            
        } catch (Exception e) {
            return Result.error("监控验证异常: " + e.getMessage());
        }
    }
}
